/**
 *
 * @file parser.h
 *
 * @brief Header file for pcap file's parser (and statistics generation module)
 * 
 * $Id $
 */

/*
 * This file is part of Tsar.
 *
 * Tsar is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tsar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Tsar.  If not, see <http://www.gnu.org/licenses/>.
 */


#ifndef PARSER_H
#define PARSER_H

/* -- S T A N D A R D  I N C L U D E S -- */


/* -- O T H E R  I N C L U D E S -- */
#include <options.h>
#include <output.h>
#include <gen_html_report.h>
#include <loop.h>

#include <pcap.h>


/* -- C O N S T A N T S -- */

/** @def no error occured while parsing pcap file */
#define PCAP_NO_ERROR       0x00
/** @def file is empty */
#define PCAP_EMPTY_FILE     0x01
/** @def the supplied filtering expression is invalid */
#define PCAP_INVALID_FILTER 0x02
/** @def an error occured while computing statistics */
#define PARSER_ERROR_STATS  0x03

/* -- M A C R O S -- */


/* -- T Y P E D E F S -- */

/** @brief list of informations about captured packets */
struct pckListEntry {
    /** @brief time when packet were captured */
    struct timeval ts;
    /** @brief next entry or NULL for the last one */
    struct pckListEntry * next;
};


/* -- F U N C T I O N S  P R O T O T Y P E S -- */
/**
 * @brief external function : fill a stats_t structure according to a pcap file and a pcap filter
 * @param filename is the file to parse
 * @pcapFilter is a null terminated string containing a pcap filter
 * @return a malloc()ed stats_t structure
 * @retval NULL on error
 */
stats_t * make_stats_from_file( char * filename, char * pcapFilter, int * errCode );

/**
 * @brief external function : free a stats_t structure obtained from a call to make_stats_from_file
 * @param statistics the structure to free
 */
void stats_free( stats_t * statistics );

/**
 * @brief apply a pcap filter on the pcap "reader"
 * @param filename the file to parse
 * @param pcapFilter a null terminated string that contains a valid (or not) pcap filter
 * @return a pcap pointer to a configured pcap session to parse the file
 * @return NULL an error occured
 */
pcap_t * set_filter( char * filename, const char * pcapFilter, int * err );

/**
 * @brief compute stats and store them into a stats_t structure
 * @param res is the address where to store computed statistics
 * @param pcap is a pcap handle to the file to parse
 * @return error code according to the execution of the function
 * @retval 0 no error
 * @retval 1 an error occured parsing packets
 */
int compute_stats( stats_t * res, pcap_t * pcap );

/**
 * @brief update a stats_t element with a new entry
 * @param res points to the structure to update
 * @param pktInfo contains some informations about the packet
 * @param starting is the hour our parsing started
 * @return error code according to the execution of the function
 * @retval 0 no error
 * @retval 1 packet arrived after we started to parse the dump, we don't take care of it
 */
int update_stats( stats_t * res, struct pcap_pkthdr * pktInfo, struct timeval * starting );

/**
 * @brief add an entry to the list of captured packets
 * @param list singly chained list of packets info
 * @param pktInfo is the pcap structure from which entry is build
 */
void add_list_entry( struct pckListEntry ** list, struct pcap_pkthdr * pktInfo );

/**
 * @brief destroy list of packets informations entries
 * @param pckl list to destroy
 */
void destroy_packets_list( struct pckListEntry * pckl );

/**
 * @brief remove the head of the list
 * @param head points to the head of the list
 */
void delete_list_head( struct pckListEntry ** head );

/**
 * @brief build a stats_t structure according to stored values from a pckList
 * @param res poibts to an allready allocated stats_t structuer to fill
 * @param pktList is the list that contains informations about captured packets
 */
int fill_stats( stats_t * res, struct pckListEntry * pktList );

/**
 * @brief check for the packet's arrival time to ensure it is before starting time
 * @param pckTv time when the packet was captured
 * @param startingTv time at which we started to parse the dump file
 * @return a boolean value according to the result
 * @retval true : the packet arrived in allowed range
 * @retval false : the packet's arrival time is out of the allowed range
 */
bool_t arrival_time_in_range( struct timeval * pckTv, struct timeval * startingTv );

/**
 * @brief split the statistics storage field into several ranges and set their names
 * @param res points to the stats_t to modify
 */
void set_stats_ranges( stats_t * res );

/**
 * @brief dispatch packet's informations into storage fields
 * @param res points to the stats_t element to update
 * @param arrivalTime is the hour when packet was captured
 */
void store_packet_stats( stats_t * res, struct timeval * arrivalTime );

#endif /* PARSER_H */

